package awesome.cpu.structure;

import awesome.cpu.utils.Mode;

public class MuxB extends NonSequentialComponent {
	
	private static boolean outputDebug = false; 
	
	public final static int KEY_ALU_SRCB = 1;
	private int mALUSrcB;
	
	public final static int KEY_REGB_SHIFTED = 2;
	private int mRegBShifted;
	final private int mAddedConst = 4;
	public final static int KEY_IMM_EXTENDED = 3;
	private int mImmExtended;
	public final static int KEY_IMM_SHIFTED = 4;
	private int mImmShifted;
	public final static int KEY_REGB_ORIG = 5;
	private int mRegBOrig;
	
	public final static int KEY_SELECTED = 5;
	//private int mSelected;
	
	private final static MuxB mInstance = new MuxB();
	
	private MuxB() {}
	
	public static MuxB getInstance() {
		return mInstance;
	}
	
	@Override
	boolean setData(int keyInterface, int data) {
		switch (keyInterface) {
		case KEY_ALU_SRCB:
			mALUSrcB = data;
			return true;
		case KEY_REGB_SHIFTED:
			mRegBShifted = data;
			return true;
		case KEY_IMM_EXTENDED:
			mImmExtended = data;
			return true;
		case KEY_IMM_SHIFTED:
			mImmShifted = data;
			return true;
		case KEY_REGB_ORIG:
			mRegBOrig = data;
			return true;
		}
		return false;
	}

	@Override
	int getData(int keyInterface) {
		
		BusMonitor.transferData(Control.getInstance(), Control.KEY_ALU_SRC_B,
				this, KEY_ALU_SRCB);
		BusMonitor.transferData(RegisterB.getInstance(), RegisterB.KEY_REGB_OUT,
				this, KEY_REGB_ORIG);
		BusMonitor.transferData(RegBShifter.getInstance(), RegBShifter.KEY_RESULT, 
				this, KEY_REGB_SHIFTED);
		BusMonitor.transferData(MuxImm2Ex.getInstance(), MuxImm2Ex.KEY_SELECTED,
				this, KEY_IMM_EXTENDED);
		BusMonitor.transferData(ImmShifter.getInstance(), ImmShifter.KEY_RESULT,
				this, KEY_IMM_SHIFTED);
		
		switch (keyInterface) {
		case KEY_SELECTED:
			int s = select();
			if (outputDebug && Mode.getDebugLevel() >= Mode.DEBUG_LEVEL_PRINT_ALL)
				System.out.println("MuxB selected = " + s);
			return s;
		}
		return 0;
	}
	
	private int select() {
		switch (mALUSrcB) {
		case 0:
			return mRegBShifted;
		case 1:
			return mAddedConst;
		case 2:
			return mImmShifted;
		case 3:
			return mImmExtended;
		case 4:
			return mRegBOrig;
		}
		return 0;
	}
}
